package com.farm.shiro.config;

import com.farm.shiro.authc.credential.BcryptCredentialsMatcher;
import com.farm.shiro.filter.AnyPermissionsAuthorizationFilter;
import com.farm.shiro.filter.AnyRolesAuthorizationFilter;
import com.farm.shiro.realm.MyRealm;
import com.farm.shiro.service.impl.PermissionService;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;

@Configuration
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class ShiroConfiguration {
    private final PermissionService permissionService;

    @Bean
    public static LifecycleBeanPostProcessor getLifecycleBeanProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    // realm
    @Bean
    public BcryptCredentialsMatcher bcryptCredentialsMatcher() {
        return new BcryptCredentialsMatcher();
    }

    @Bean
    public MyRealm customRealm() {
        MyRealm realm = new MyRealm();
        realm.setCredentialsMatcher(bcryptCredentialsMatcher());
        return realm;
    }

//    remember me
//    @Bean
//    public SimpleCookie rememberMeCookie() {
//        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//        simpleCookie.setMaxAge(259200);
//        return simpleCookie;
//    }

//    @Bean
//    public CookieRememberMeManager customRememberMeManager() {
//        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
//        cookieRememberMeManager.setCookie(rememberMeCookie());
//        cookieRememberMeManager.setCipherKey("HAND_CT@DY_TALENT".getBytes());
//        return cookieRememberMeManager;
//    }

//    redis 缓存
//    @Bean
//    public RedisManager redisManager() {
//        RedisManager redisManager = new RedisManager();
//        redisManager.setHost(host);
//        redisManager.setPort(port);
//        redisManager.setTimeout(timeout);
//        return redisManager;
//    }

//    @Bean
//    public RedisCacheManager customCacheManager() {
//        RedisCacheManager redisCacheManager = new RedisCacheManager();
//        redisCacheManager.setRedisManager(redisManager());
//        redisCacheManager.setKeyPrefix(CACHE_KEY);
//        // 配置缓存的话要求放在session里面的实体类必须有个id标识 注：这里id为用户表中的主键，否则报错：User must has getter for field: xx
//        redisCacheManager.setPrincipalIdFieldName("id");
//        return redisCacheManager;
//    }

//    @Bean
//    public ShiroSessionIdGenerator sessionIdGenerator(){
//        return new ShiroSessionIdGenerator();
//    }

//    @Bean
//    public RedisSessionMapper redisSessionMapper() {
//        RedisSessionMapper mapper = new RedisSessionMapper();
//        redisSessionDAO.setRedisManager(redisManager());
//        redisSessionDAO.setSessionIdGenerator(sessionIdGenerator());
//        redisSessionDAO.setKeyPrefix(SESSION_KEY);
//        redisSessionDAO.setExpire(EXPIRE);
//        return redisSessionDAO;
//    }

//    redis 会话
//    @Bean
//    public SessionManager customSessionManager() {
//        ShiroSessionManager shiroSessionManager = new ShiroSessionManager();
//        shiroSessionManager.setSessionDAO(redisSessionDAO());
//        return shiroSessionManager;
//    }

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//        securityManager.setRememberMeManager(customRememberMeManager());
//        securityManager.setCacheManager(customCacheManager());
//        securityManager.setSessionManager(customSessionManager());
        securityManager.setRealm(customRealm());
        return securityManager;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 设置 Security Manager
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 设置自定义过滤器
        LinkedHashMap<String, Filter> filters = new LinkedHashMap<>();
        filters.put("anyPerms", new AnyPermissionsAuthorizationFilter());
        filters.put("anyRoles", new AnyRolesAuthorizationFilter());
        shiroFilterFactoryBean.setFilters(filters);

        // TODO 设置常规认证 URL
//        shiroFilterFactoryBean.setLoginUrl("");
//        shiroFilterFactoryBean.setSuccessUrl("");
//        shiroFilterFactoryBean.setUnauthorizedUrl("");

        // 设置 URL 鉴权链
        shiroFilterFactoryBean.setFilterChainDefinitionMap(permissionService.loadFilterChainDefinitionMap());

        return shiroFilterFactoryBean;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

}

